package uima.stanford.parser;




import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import edu.stanford.nlp.ling.Word;
import edu.stanford.nlp.parser.lexparser.LexicalizedParser;
import edu.stanford.nlp.process.Tokenizer;
import edu.stanford.nlp.trees.Constituent;
import edu.stanford.nlp.trees.GrammaticalStructure;
import edu.stanford.nlp.trees.GrammaticalStructureFactory;
import edu.stanford.nlp.trees.PennTreebankLanguagePack;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TreeGraphNode;
import edu.stanford.nlp.trees.TreePrint;
import edu.stanford.nlp.util.IntPair;

public class Parser {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) {		
		
		
		
		LexicalizedParser parser = new LexicalizedParser("resources/englishPCFG.ser.gz");
		String text = new String("the dog eats the cat in the garden");
		parser.parse(text);	
		
		
		
		
		//tokenizer
		PennTreebankLanguagePack tblp = new PennTreebankLanguagePack();
		Tokenizer<Word> tokenizer = tblp.getTokenizerFactory().getTokenizer(new StringReader(text));
		List<Word> wordList = tokenizer.tokenize();		
		Tree parseTree =  (Tree) parser.apply(wordList);
		TreePrint treePrint =  new TreePrint("penn,wordsAndTags");
		//TreePrint treePrint =  new TreePrint("wordsAndTags");
		treePrint.printTree(parseTree);	
		
		GrammaticalStructureFactory gsf = tblp.grammaticalStructureFactory();
		GrammaticalStructure gs = gsf.newGrammaticalStructure(parseTree);	
		
		TreeGraphNode start = gs.root().children()[0];
		if(start == null){
			System.out.println("ERRORE");
			return;
		}
		
		Iterator<TreeGraphNode> iter;
		
//		iter = gs.getNodes().iterator();
//		for(int i=0;i<wordList.size();i++){
//			TreeGraphNode node = iter.next();			
//			Word w = wordList.get(i);
//			System.out.println("WORD "+w.value());
//			System.out.println("\tBEGIN "+w.beginPosition());
//			System.out.println("\tEND "+w.endPosition());			
//			System.out.println("\tTAG "+node.label().tag());
//			System.out.println("\t");
//		}
		
		
		iter = gs.getNodes().iterator();
		while(iter.hasNext()){
			TreeGraphNode node = iter.next();
			if(!node.label().value().equals("ROOT")){
				node.setSpans();
				System.out.println(node.label().value());				
				if(node.isLeaf()){
					System.out.println("\tTAG "+node.label().tag());
					int nodeIndex = node.index();
					System.out.println("\tBEGIN "+wordList.get(nodeIndex-1).beginPosition());
					System.out.println("\tEND "+wordList.get(nodeIndex-1).endPosition());
				}
				else{
					ArrayList<TreeGraphNode> nodeLeaves = getLeaves(node);
					int firstIndex = nodeLeaves.get(0).index();
					int lastIndex = nodeLeaves.get(nodeLeaves.size()-1).index();
					System.out.println("\tBEGIN "+wordList.get(firstIndex-1).beginPosition());
					System.out.println("\tEND "+wordList.get(lastIndex-1).endPosition());
				}
			}			
		}
		
	}
	
	public static ArrayList<TreeGraphNode> getLeaves(TreeGraphNode node){
		ArrayList<TreeGraphNode> leaves = new ArrayList<TreeGraphNode>();
		if(node.isPreTerminal()){
			
			if(node.isLeaf()){
				leaves.add(node);
			}
			else{
				leaves.add(node.children()[0]);
			}				
			return leaves;
		}
		else{
			TreeGraphNode[] children = node.children();
			ArrayList<TreeGraphNode> tmpLeavesFirst = getLeaves(children[0]);
			ArrayList<TreeGraphNode> tmpLeavesLast = getLeaves(children[children.length-1]);
			leaves.addAll(tmpLeavesFirst);
			leaves.addAll(tmpLeavesLast);
			return leaves;
		}
	}
	
	
}
